home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Night Owl 6
/
Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso
/
029a
/
readm110.zip
/
README.PAS
< prev
Wrap
Pascal/Delphi Source File
|
1990-01-31
|
24KB
|
575 lines
program readme;
{ Name: Readme.pas -> Readme.exe }
{ Version: 1.10 }
{ Date: January 2, 1990 }
{ Purpose: a text file browse utility }
{ Compiler: Turbo Pascal 5.50 }
{ Hardware: XT,AT,386 or PS/2 }
{ Video: CGA,MDA,Herc,EGA or VGA }
{ Video Modes: 2, 3 or 7 }
{ By: J. Rockford Cogar }
{ Company: Nucleus Inc }
{ Address: 761 Emory Valley Road, Oak Ridge, TN 37830 }
{ Rights: Use this code any way you want }
{ Parameters: README <filename> }
{ -------------------- About Video 'Snow' ---------------------------------- }
{ This is a rewrite of a Turbo 'C' program that used to include code }
{ to deal with CGA write contention problems ('snow'). That code was }
{ removed because all Nucleus Inc. software requires EGA or VGA video }
{ systems that do not have 'snow'. Late in January 1990, I will release }
{ the Turbo 'C' version of README. That program will contain video functions }
{ that avoids CGA 'snow'. }
{ -------------------------------------------------------------------------------- }
{ ----------------------- Constants ---------------------------------------------- }
CONST
DEFAULT_EXT : string[4] = '.c'; { default file extension }
NOFILE : string[15] = 'File Not Found';
READERROR : string[16] = 'File Read Error';
RAMERROR : string[15] = 'Not Enough RAM';
NORMAL : string[19] = 'Normal Termination.';
WRONGVIDEO : string[30] = 'Error. can only use text mode';
DEFAULT : string[65] = 'readme.doc'; { file to load when none was specified on the command line }
SEARCHING : string[10] = 'Searching';
SPROMPT : string[6] = 'Find:';
AUTHOR : string[27] = 'Author: J. Rockford Cogar';
PGNAME : string[62] = 'README.EXE File Browser. by: Nucleus Inc. Oak Ridge TN 37830';
WRIT : string[28] = 'Written in Turbo Pascal 5.5';
LINEPR : string[15] = 'Reading Record:';
STAT1 : string[69] = 'Row: 0 of: in RAM Left Column: 0 Right Column: 79';
STAT2 : string[55] = 'Up = | Down = | Left = - Right = - Exit = Esc';
STAT3 : string[52] = 'Help = F1 End of File = End Ascii Search = F9';
HELP1 : string[47] = 'Home = Top of File End = End of File';
HELP2 : string[46] = 'PgUp = Page Up PgDn = Page Down';
HELP3 : string[54] = 'Up Arrrow = Scroll Up Down Arrrow = Scoll Down';
HELP4 : string[57] = 'Left Arrrow = Scroll Left Right Arrrow = Scroll Right';
HELP5 : string[47] = 'Esc = Exit to DOS F9 String Search';
HELP6 : string[26] = 'A = Repeat String Search';
SIDEJUMP = 20; { columns to scroll sideways }
SEARLEN = 20; { number of bytes in a search string }
NORMALEXIT = 0; { normal exit code to DOS }
ERROREXIT = 1; { error exit code to DOS }
VIDEOEXIT = 2; { wrong video EXIT }
NUMBLINES = 9000; { max number of allowed lines }
TEXTCOLOR = 31; { color to show normal text in }
STATUSCOLOR = 49; { command/status color }
BLINKCOLOR = 207; { blinking color }
FINDCOLOR = 79; { color of found strings }
PAGESIZE = 21; { pageup/pagedown line lengths }
_ESC = 1; { Esc scan code }
_PGUP = 73; { Page Up key }
_PGDN = 81; { Page DN key }
_UPAR = 72; { Up arrow key }
_DNAR = 80; { down arrow key }
_F9 = 67; { F9 key }
_F1 = 59; { F1 key }
_RIAR = 77; { right arrow key }
_LEAR = 75; { left arraow key }
_HOME = 71; { Home key }
_END = 79; { End key }
_H = 35; { 'h' key }
_X = 45; { 'x' key }
_S = 31; { 's' key }
_A = 30; { 'a' key }
LEFTMAX = 175; { greatest allowed left edge of the display }
{ ----------------------- Constants ---------------------------------------------- }
{ ----------------------- Special Data TYPES ---------------------------------------------- }
TYPE
BUFF_TYPE = string[254]; { the type that a buffer line is }
BUFFER_PTR = ^BUFF_TYPE; { pointer to a 254 byte string }
SEARCH_TYPE = string[SEARLEN]; { string of a specified length for string search uses }
STRING128 = string[128]; { filename string type. (command line params can be this long) }
{ ----------------------- Special Data TYPES ---------------------------------------------- }
{ ----------------------- Global Variables ---------------------------------------------- }
VAR
linestr : SEARCH_TYPE; { processed search string }
iname : STRING128; { filename var }
buffer : array [0..NUMBLINES] of BUFFER_PTR; { pointers to 9000 strings }
max : integer; { loop stop point }
key : integer; { keyboard scan code value }
refresh : boolean; { refresh the screen }
star : integer; { first text line to display }
row : integer; { row to display }
left : integer; { left edge of screen }
find : integer; { set to -1 if no string was found }
{ ----------------------- Global Variables ---------------------------------------------- }
{ ---- link in assembly language functions (faster & smaller than using standard libraries) ---- }
procedure snowputc(col, row, color, outch, numb: word); external;
procedure cursorxy(col, row: byte); external;
function getscode: integer; external;
procedure puts(strg :string); external;
function getvmode: integer; external;
function readkbd: integer; external;
function cgets(VAR strg : SEARCH_TYPE): integer; external;
procedure snowwrite(col, row: integer; color: byte; ptr: buffer_ptr; soff, maxchars, clrchar: integer); external;
{$L conio.obj } { assemble CONIO.ASM (with Turbo Assembler) to make CONIO.OBJ }
{ setup a different heap error handler }
{ ------------------------- Begin HeapFunc --------------------------------------- }
{$F+} function HeapFunc(Size: word): integer; {$F-}
begin
HeapFunc:=1;
end;
{ ------------------------- End HeapFunc --------------------------------------- }
{ clear the screen, write exit msg & go to DOS }
{ ------------------------- Begin ExiToDos --------------------------------------- }
procedure ExitToDos(ret :integer; msg: string);
begin
if (ret <> VIDEOEXIT) then
begin
snowputc(0,0,TEXTCOLOR,32,2000); { clear the screen }
end;
cursorxy(0,0); { mode the cursor }
puts(msg); { display exit msg }
halt(ret); { return an errorlevel code }
end;
{ ------------------------- End ExitToDos --------------------------------------- }
{ this draws the help screen }
{ ------------------------- Begin Help --------------------------------------- }
procedure help;
VAR
ky : integer; { dummy var for readkbd() }
begin
{ all messages are global typed constants }
snowputc(0,1,TEXTCOLOR,32,1760); { clear the data area }
snowwrite(8, 2, TEXTCOLOR,addr(PGNAME),0,80,80); { program Name }
snowwrite(0, 4, TEXTCOLOR,addr(HELP1),0,80,80); { Help message #1 }
snowwrite(0, 6, TEXTCOLOR,addr(HELP2),0,80,80); { Help message #2 }
snowwrite(0, 8, TEXTCOLOR,addr(HELP3),0,80,80); { Help message #3 }
snowwrite(0, 10,TEXTCOLOR,addr(HELP4),0,80,80); { Help message #4 }
snowwrite(0, 12,TEXTCOLOR,addr(HELP5),0,80,80); { Help message #5 }
snowwrite(0, 14,TEXTCOLOR,addr(HELP6),0,80,80); { Help message #6 }
refresh:=TRUE; { redraw screen later }
ky:=readkbd; { pause for a scan code from kbd }
end;
{ ------------------------- End Help --------------------------------------- }
{ backwards POS(). return the offset into STRING str of CHAR ch. ret -1 if not found }
{ ------------------------- Begin rpos --------------------------------------- }
function rpos(str: string; ch: char): integer;
Var i: integer; { loop index }
loc: integer; { location of the find }
begin
i:=length(str); { string length }
loc:=-1; { assume failure! }
{ ---------------------- search loop ------------------------------- }
while (i > 0) and (loc = -1) do { loop backwards through the string }
begin
if (str[i] = ch) then { got a match }
begin
loc:=i; { save the index of the location }
end;
dec(i); { look one byte leftwards }
end;
{ ---------------------- search loop ------------------------------- }
rpos:=loc; { the location of the find. -1 if no find }
end;
{ ------------------------- End rpos --------------------------------------- }
{ this draws the screen for the text file browser }
{ ------------------------- begin video_setup --------------------------------------- }
procedure Video_Setup;
Var
vmode: integer; { current video mode }
begin
vmode:=getvmode; { get current video mode }
if (vmode < 2) or (vmode > 7) or (vmode = 4) or (vmode = 5) or (vmode = 6) then
begin
ExitToDos(VIDEOEXIT,WRONGVIDEO);
end;
snowputc(0,1,TEXTCOLOR,32,1760); { clear the screen }
snowwrite(8,10,TEXTCOLOR,addr(PGNAME),0,72,72); { program Name }
snowwrite(0, 0,STATUSCOLOR,addr(STAT1),0,80,80); { status message #1 }
snowputc(0,23,STATUSCOLOR,32,20);
snowwrite(20,23,STATUSCOLOR,addr(STAT2),0,60,60); { status message #2 }
snowputc(0,24,STATUSCOLOR,32,20);
snowwrite(20,24,STATUSCOLOR,addr(STAT3),0,60,60); { status message #3 }
snowputc(25,23,STATUSCOLOR,24,1); { ascii 24 up }
snowputc(36,23,STATUSCOLOR,25,1); { ascii 25 down }
snowputc(47,23,STATUSCOLOR,27,1); { ascii 27 left }
snowputc(59,23,STATUSCOLOR,26,1); { ascii 26 right }
cursorxy(0,24); { home the cursor }
end;
{ ------------------------- End video_setup --------------------------------------- }
{ this initializes a filename variable }
{ ------------------------- begin Set_Filename --------------------------------------- }
procedure Set_Filename(VAR ifname: STRING128);
Var
dotloc: integer; { location of the dot in the filename }
begin
if (paramcount > 0) then
begin
ifname:=paramstr(1); { fetch com line filename }
end
else
begin
ifname:=DEFAULT; { use the default filename when none was specified }
end;
dotloc:=pos('.',ifname); { get offset of '.' }
if (dotloc = 0) then { append a default extension on the filename var }
begin
ifname:=ifname + DEFAULT_EXT;
end;
end;
{ ------------------------- End Set_Filename --------------------------------------- }
{ this reads the file from disk into global variable: buffer[] }
{ ------------------------- Begin Read_File --------------------------------------- }
function Read_File(ifname: string): integer;
Var
inf : text; { file pointer }
strg : string; { scaler string var }
line : integer; { line index }
len : integer; { line length }
linestr : string[20]; { str to show current line # }
begin
line:= 0; { zero line counter }
assign(inf,ifname);
{$I-} reset(inf); {$I+}
if (IOResult <> 0) then ExitToDos(ERROREXIT,NOFILE); { no file. exit }
snowwrite(24,12,TEXTCOLOR,addr(LINEPR),0,15,15); { status msg }
{ ------- write the root of the filename on the CRT ------ }
if (length(ifname) < 19) then
begin
snowwrite(0,23,STATUSCOLOR,addr(ifname),0,19,19); { write the filename on the screen }
end
else { a complex filename is being processed }
begin
len:=rpos(ifname,'\'); { get offset into string of '\' }
linestr:=copy(ifname, len + 1, 19); { copy just the root into linestr }
snowwrite(0,23,STATUSCOLOR,addr(linestr),0,19,19); { write the filename on the screen }
end;
{ ---- Read lines from file Loop ---- }
while NOT EOF(inf) and (line < NUMBLINES) and (MaxAvail > 1024) do
begin
{$I-}
readln(inf,strg); { read a line from the file }
{$I+}
if (IOResult <> 0) then { read error }
begin
close(inf);
ExitToDos(ERROREXIT,READERROR); { Read error. exit }
end;
len:=length(strg) + 1; { get line length }
getmem(buffer[line], len); { get heap RAM for the array line }
if (buffer[line] = NIL) then { if getmem() failed }
begin
close(inf);
ExitToDos(ERROREXIT,RAMERROR);
end;
move(strg,buffer[line]^,len); { copy the scaler string to the array }
if ( (line mod 64) = 0) then { every 64 lines update count on the CRT }
begin
str(line,linestr); { convert line index to string }
snowwrite(40,12,TEXTCOLOR,addr(linestr),0,6,6);
end;
inc(line); { inc the line counter }
end; { while end }
close(inf);
strg:=' '; { reinit to a known state }
{ ----------- padd lines for very short text files ---------------- }
while (line <= PAGESIZE) do
begin
getmem(buffer[line], 3); { get heap RAM for the ' ' empty array lines }
move(strg,buffer[line]^,3); { copy the scaler string to the array }
inc(line); { inc the line counter }
end;
{ ----------- padd lines for very short text files ---------------- }
str(line - 1,linestr); { convert line index to string }
snowwrite(14,0,STATUSCOLOR,addr(linestr),0,5,5);
snowputc(0,10,TEXTCOLOR,32,240);
Read_File:=line - 1;
end;
{ ------------------------- End Read_File --------------------------------------- }
{ this displays the text data on the CRT }
{ ------------------------- Begin Write_Data --------------------------------------- }
procedure Write_Data(star, left, find: integer);
Var
starstr: string[34]; { counter display string }
line : integer; { data buffer index }
row : integer; { CRT row index }
lstop : integer; { loop stop point }
begin
{ note: buffer[] is a global variable }
str(star,starstr); { convert start index to string }
snowwrite(5,0,STATUSCOLOR,addr(starstr),0,5,5);
str(left,starstr); { left edge column }
snowwrite(48,0,STATUSCOLOR,addr(starstr),0,3,3);
str(left + 79,starstr); { Right edge column }
snowwrite(66,0,STATUSCOLOR,addr(starstr),0,3,3);
row:=1; { first line to write text to }
lstop:=star + PAGESIZE; { set loop stop point }
for line:=star to lstop do
begin
if (find > -1) and (line = find) then snowwrite(0,row,FINDCOLOR,addr(buffer[line]^),left,80,80)
else snowwrite(0,row,TEXTCOLOR,addr(buffer[line]^),left,80,80); { write the text to the CRT }
inc(row); { next CRT row }
end;
end;
{ ------------------------- End Write_Data --------------------------------------- }
{ this does the string search. (case sensitive) }
{ ------------------------- Begin Search --------------------------------------- }
function search(start, max : integer; sstr: string) : integer;
VAR
i : integer; { loop index }
ok: byte; { position of the substring }
begin
{ note: buffer[] is a global variable }
ok:=0; { assume failure }
i:=start; { loop start point }
{ search through the buffer for the string }
while (ok = 0) and (i <= max) do
begin
ok:=pos(sstr, buffer[i]^); { search the text line }
inc(i); { point to the next text line }
end;
if (i <= (max + 1) ) and (ok > 0) then
begin
search:=i - 1; { return line of the find }
end
else
begin
search:=-1; { no find }
end;
end;
{ ------------------------- End Search --------------------------------------- }
{ prompt user for string to search, then do the search }
{ ------------------------- Begin String_Search --------------------------------------- }
function String_Search(key: integer; VAR refresh: boolean; VAR star: integer): integer;
Var
off_set : integer; { offset in start of string search }
len : integer; { line length }
lfind : integer; { line of the search find }
searchstr : SEARCH_TYPE; { ascii search string }
begin
{ linestr is a global variable }
if (key <> _A) then
begin
cursorxy(6,24); { home the cursor }
snowwrite(0,24,STATUSCOLOR,addr(SPROMPT),0,20,20); { write prompt }
searchstr[0]:=#14; { max numb bytes of input }
len:=cgets(searchstr); { get string from the user }
cursorxy(0,24); { home the cursor }
linestr:=copy(searchstr,2,len); { copy the useful data to another string }
off_set:=0; { start search on the current line }
end
else
begin
off_set:=1; { start search on line below current one }
end;
snowwrite(0,24,BLINKCOLOR,addr(SEARCHING),0,20,20); { searching msg }
len:=search(star + off_set,max,linestr);
if (len > -1) then { if string was found }
begin
refresh:=TRUE; { set to refresh the data on the CRT }
star:=len; { first line to display }
lfind:=len; { line of the find }
if (lfind < 0) then lfind:=0; { range check find }
if (star > (max - PAGESIZE)) then star:=max - PAGESIZE; { last page case for starting line }
end
else
begin
lfind:=-1; { no string was found }
end;
snowputc(0,24,STATUSCOLOR,32,20);
snowwrite(20,24,STATUSCOLOR,addr(STAT3),0,80,80); { status message #3 }
String_Search:=lfind; { return the line number of the search find }
end;
{ ------------------------- End String_Search --------------------------------------- }
{ ------------------------- Begin Init_Globals --------------------------------------- }
procedure Init_Globals;
begin
HeapError:=@HeapFunc; { set up our own getmem() error handler }
left:=0; { initial left edge is zero }
refresh:=FALSE; { no refresh yet }
find:=-1; { no find yet }
star:=0; { start at first line }
key:=0; { init scan code to zero }
linestr:=' '; { initail search string }
end;
{ ------------------------- End Init_Globals --------------------------------------- }
{ ------------------------- Begin Main (ie: main loop proc) ------------------ }
begin
Init_Globals; { initialize global variables }
Video_Setup; { draw the screen }
Set_Filename(iname); { initialize the filename variable (iname) }
max:=Read_File(iname); { read the file from disk into buffer[] }
Write_Data(0, 0, -1); { write data to the CRT }
{ ------------------------------ Main Loop --------------------------------- }
while (key <> _ESC) do { loop till the Esc key is pressed }
begin
key:=getscode; { get current scan key code }
{ -------------------------- Case Block ---------------------------- }
case (key) of { begin case }
_PGUP: { PageUp key }
begin
star:=star - PAGESIZE;
if (star < 0) then
begin
star:=0;
end;
refresh:=TRUE;
end;
_PGDN: { PageDown key }
begin
star:=star + PAGESIZE;
if ( (star + PAGESIZE) > max) then
begin
star:=max - PAGESIZE;
end;
refresh:=TRUE;
end;
_UPAR: { UpArrow key }
begin
if (star > 0) then
begin
dec(star);
refresh:=TRUE;
end;
end;
_DNAR: { Down Arrow key }
begin
if ( (star + PAGESIZE) < max) then
begin
inc(star);
refresh:=TRUE;
end;
end;
_RIAR: { right arrow key }
begin
left:=left + SIDEJUMP;
if (left > LEFTMAX) then left:=0;
refresh:=TRUE;
end;
_LEAR: { left arrow key }
begin
left:=left - SIDEJUMP;
if (left < 0) then left:=0;
refresh:=TRUE;
end;
_HOME: { Home key }
begin
star:=0;
refresh:=TRUE;
end;
_END : { End key }
begin
if (max >= PAGESIZE) then
begin
star:=max - PAGESIZE;
end
else
begin
star:=0;
end;
refresh:=TRUE;
end;
_F9,_S,_A : { string search keys }
begin
find:=String_Search(key, refresh, star); { Ascii String Search }
end;
_H,_F1: { 'h' key HELP Screen }
begin
help; { show help screen }
end;
_X : { 'x' key }
begin
key:=_ESC;
end;
end; { end case }
{ -------------------------- Case Block ---------------------------- }
if (refresh) then { if time to update CRT data }
begin
refresh:=FALSE; { toggle to avoid doing too much CRT stuff }
Write_Data(star, left, find); { write data to the CRT }
end;
end; { end while loop }
{ ------------------------------ Main Loop --------------------------------- }
ExitToDos(NORMALEXIT,NORMAL);
end.
{ ------------------------- End Main --------------------------------------- }